package com.rdgk.newtech.service.impl;

import com.rdgk.newtech.dao.*;
import com.rdgk.newtech.service.AuthorAnalyseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class AuthorAnalyseServiceImpl implements AuthorAnalyseService {
    @Autowired
    private TechniqueArticleDao techArticleDao;
    @Autowired
    private PaperDao paperDao;
    @Autowired
    private PatentDao patentDao;
    @Autowired
    private CraOrganizationDao organizationDao;
    @Autowired
    private TechniqueWordDao techniqueWordDao;
    @Autowired
    private CraAuthorDao authorDao;



    @Override
    public List<Map<String,Object>> importantAuthorList(Integer topicId, String[] words) {//
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        return authorDao.getImportantAuthors(params);
    }

    @Override
    public List<Map<String,Object>> technologyRegionalDistribution(Integer topicId, String[] words) {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        return authorDao.statisticsAuthorNumForMap(params);
    }

    @Override
    public Map<String, Object> allAuthorCooperateNet(Integer topicId, String keyword) {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("keyword",keyword);
        Map<String,Object> results = new HashMap<String,Object>();
        List<Map<String,Object>> nodes = new ArrayList<Map<String,Object>>();//节点列表
        List<Map<String,Object>> edges = new ArrayList<Map<String,Object>>();//关系列表
        List<Map<String,Object>> authorNodes = new ArrayList<Map<String,Object>>();//专家节点
        List<Map<String,Object>> authorEdges = new ArrayList<Map<String,Object>>();//专家与网络新闻动态关系
        Map<Object,List<Object>> relatedAuthorList = new HashMap<Object,List<Object>>();
        Map<String,Integer> relIndex = new HashMap<String,Integer>();//记录关系元素在关系列表中的下标
        List<Map<String,Object>> hotwordArticle = techArticleDao.getArticleByHotword(params);
        List<Object> articleIdParams = new ArrayList<Object>();//用于传递参数的网络新闻动态id的集合
        for (Map<String,Object> article:hotwordArticle
             ) {
            if(!articleIdParams.contains(article.get("articleid"))){
                articleIdParams.add(article.get("articleid"));//保存每个网络新闻动态的id
            }
        }
        List<Map<String,Object>> hotwordPaper = paperDao.getPaperByHotword(params);
        List<Object> paperIdParams = new ArrayList<Object>();//用于传递参数的论文id的集合
        for (Map<String,Object> paper:hotwordPaper
                ) {
            if(!paperIdParams.contains(paper.get("paperid"))){
                paperIdParams.add(paper.get("paperid"));
            }
        }
        List<Map<String,Object>> hotwordPatent = patentDao.getPatentByHotword(params);
        List<Object> patentIdParams = new ArrayList<Object>();//用于传递参数的论文id的集合
        for (Map<String,Object> patent:hotwordPatent
                ) {
            if(!patentIdParams.contains(patent.get("patentid"))){
                patentIdParams.add(patent.get("patentid"));
            }
        }
        params.put("relArticleList",articleIdParams);
        params.put("relPaperList",paperIdParams);
        params.put("relPatentList",patentIdParams);
        List<Map<String,Object>> relAuthors = authorDao.getAuthorByHotword(params);
        List<Object> tmpAuthorIds = new ArrayList<Object>();//临时存放专家id的list，用于去重
        for (Map<String,Object> relAuthor:relAuthors
             ) {
            Object authorid = relAuthor.get("authorid");
            if(!tmpAuthorIds.contains(authorid)){//判断专家id是否已经出现过
                Map<String,Object> authorNode = new HashMap<String,Object>();//创建专家节点
                authorNode.put("id","author_"+relAuthor.get("authorid"));
                authorNode.put("label",relAuthor.get("name"));
                authorNodes.add(authorNode);
                tmpAuthorIds.add(authorid);//标记该专家已经出现过
            }
            Object articleid = relAuthor.get("targetID")+"_"+relAuthor.get("reltype");//与专家相关的新闻动态、论文、专利的id
            List<Object> authorList = relatedAuthorList.get(articleid);
            if(authorList==null||authorList.size()<=0){
                authorList = new ArrayList<Object>();
                authorList.add(relAuthor.get("authorid"));
            }else{
                if(!authorList.contains(relAuthor.get("authorid")))
                    authorList.add(relAuthor.get("authorid"));
            }
            relatedAuthorList.put(articleid,authorList);
        }
        Set<Object> articleKeys = relatedAuthorList.keySet();
        for (Object articleKey:articleKeys
                ) {//给热词节点的size属性赋值
            List<Object> authorList = relatedAuthorList.get(articleKey);
            if(authorList==null)
                continue;
            for (int i = 0;i<authorList.size()-1;i++){
                Object authorid = authorList.get(i);
                for (int j = 1;j<authorList.size();j++) {
                    if (relIndex.get(authorid + "rel" + authorList.get(j)) == null && relIndex.get(authorList.get(j) + "rel" + authorid) == null) {
                        Map<String, Object> authorEdge = new HashMap<String, Object>();
                        authorEdge.put("sourceID", "author_" + authorid);
                        authorEdge.put("targetID", "author_" + authorList.get(j));
                        authorEdge.put("size", 1);
                        relIndex.put(authorid + "rel" + authorList.get(j), authorEdges.size());
                        authorEdges.add(authorEdge);
                    } else {
                        Integer index = (relIndex.get(authorList.get(j) + "rel" + authorid) == null) ? relIndex.get(authorid + "rel" + authorList.get(j)) : relIndex.get(authorList.get(j) + "rel" + authorid);
                        Map<String, Object> authorEdge = authorEdges.get(index);
                        Integer size = (Integer) authorEdge.get("size");
                        authorEdge.put("size", ++size);
                    }
                }
            }
        }
        //将所有节点增加到nodes集合中
        nodes.addAll(authorNodes);
        //将所有关系增加到edges集合中
        edges.addAll(authorEdges);
        //将关系和节点列表添加到结果集中
        results.put("nodes",nodes);
        results.put("edges",edges);
        return results;
    }

    private void computeSize(Map<Object,Integer> nodeSize,Object nodeId){
        Integer size = nodeSize.get(nodeId);
        nodeSize.put(nodeId,size==null?1:++size);
    }

    @Override
    public Map<String,Object>  authorDetail(Integer topicId,Integer authorId){
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("authorId",authorId);
        Map<String,Object> results = new HashMap<String,Object>();
        List<Map<String,Object>> nodes = new ArrayList<Map<String,Object>>();//节点列表
        List<Map<String,Object>> edges = new ArrayList<Map<String,Object>>();//关系列表

        List<Map<String,Object>> authorNodes = new ArrayList<Map<String,Object>>();//专家节点
        List<Map<String,Object>> authorEdges = new ArrayList<Map<String,Object>>();//专家与网络新闻动态关系
        List<Map<String,Object>> techNums = new ArrayList<Map<String,Object>>();//技术动态统计数据

        Map<Object,List<Object>> relatedAuthorList = new HashMap<Object,List<Object>>();
        Map<String,Integer> relIndex = new HashMap<String,Integer>();//记录关系元素在关系列表中的下标

        List<Object> articleIdParams = new ArrayList<Object>();//用于传递参数的网络新闻动态id的集合
        List<Object> paperIdParams = new ArrayList<Object>();//用于传递参数的论文id的集合
        List<Object> patentIdParams = new ArrayList<Object>();//用于传递参数的论文id的集合
        List<Object> authorIdParams = new ArrayList<Object>();//用于传递参数的专家id的集合

        List<Map<String,Object>> authorfos = authorDao.getAuthorByID(params);
        Map<String,Object> authordetail = authorfos.size()>0?authorfos.get(0):null;//机构详情
        Map<String,Object> authorNode = new HashMap<String,Object>();
        authorNode.put("id","author_"+authordetail.get("id"));
        authorNode.put("label",authordetail.get("NAME"));
        authorNodes.add(authorNode);
        authorIdParams.add(authordetail.get("id"));

        List<Map<String,Object>> hotworddata = new ArrayList<Map<String,Object>>();//机构相关热词
        hotworddata = authorDao.getAuthorHotwords(params);

        List<Map<String,Object>> orgs = new ArrayList<Map<String,Object>>();//机构相关专家
        orgs = authorDao.getAuthorOrgs(params);

        List<Map<String,Object>> authorTechEvents = new ArrayList<Map<String,Object>>();//专家相关技术动态
        authorTechEvents = authorDao.getAuthorTechEvents(params);
        for (Map<String,Object> authorTechEvent:authorTechEvents
                ) {
            if("0".equals(authorTechEvent.get("reltype"))){//创建专家与论文关系
                if(!articleIdParams.contains(authorTechEvent.get("id"))) {
                    articleIdParams.add(authorTechEvent.get("id"));
                }
            }
            if("1".equals(authorTechEvent.get("reltype"))){//创建专家与论文关系
                if(!paperIdParams.contains(authorTechEvent.get("id"))) {
                    paperIdParams.add(authorTechEvent.get("id"));
                }
            }
            if("2".equals(authorTechEvent.get("reltype"))) {//创建专家与专利关系{
                if(!patentIdParams.contains(authorTechEvent.get("id"))) {
                    patentIdParams.add(authorTechEvent.get("id"));
                }
            }
        }
        params.put("relArticleList",articleIdParams);
        params.put("relPaperList",paperIdParams);
        params.put("relPatentList",patentIdParams);
        List<Map<String,Object>> relatedAuthors =  authorDao.getAuthorRelatedAuthors(params);
        for (Map<String,Object> relatedAuthor:relatedAuthors
                ) {
            Map<String,Object> relatedAuthorNode = new HashMap<String,Object>();
            if(!authorIdParams.contains(relatedAuthor.get("caid"))) {
                relatedAuthorNode.put("id", "author_"+relatedAuthor.get("caid"));
                relatedAuthorNode.put("label", relatedAuthor.get("caname"));
                authorNodes.add(relatedAuthorNode);
                authorIdParams.add(relatedAuthor.get("caid"));
            }
            Object articleid = relatedAuthor.get("id")+"_"+relatedAuthor.get("reltype");//与专家相关的新闻动态、论文、专利的id
            List<Object> authorList = relatedAuthorList.get(articleid);
            if(authorList==null||authorList.size()<=0){
                authorList = new ArrayList<Object>();
                authorList.add(relatedAuthor.get("caid"));
            }else{
                if(!authorList.contains(relatedAuthor.get("caid")))
                    authorList.add(relatedAuthor.get("caid"));
            }
            relatedAuthorList.put(articleid,authorList);
        }

        Set<Object> articleKeys = relatedAuthorList.keySet();
        for (Object articleKey:articleKeys
                ) {//给热词节点的size属性赋值
            List<Object> authorList = relatedAuthorList.get(articleKey);
            if(authorList==null)
                continue;
            Object authorid = authorId;
            for (int i = 0;i<authorList.size();i++){
                if(authorid!=authorList.get(i)){
                    if(relIndex.get(authorid+"rel"+authorList.get(i))==null&&relIndex.get(authorList.get(i)+"rel"+authorid)==null){
                        Map<String,Object> authorEdge = new HashMap<String,Object>();
                        authorEdge.put("sourceID", "author_" + authorid);
                        authorEdge.put("targetID", "author_" + authorList.get(i));
                        authorEdge.put("size", 1);
                        relIndex.put(authorid+"rel"+authorList.get(i),authorEdges.size());
                        authorEdges.add(authorEdge);
                    }else{
                        Integer index = (relIndex.get(authorList.get(i)+"rel"+authorid)==null)?relIndex.get(authorid+"rel"+authorList.get(i)):relIndex.get(authorList.get(i)+"rel"+authorid);
                        Map<String,Object> authorEdge = authorEdges.get(index);
                        Integer size = (Integer)authorEdge.get("size");
                        authorEdge.put("size", ++size);
                    }
                }
            }
        }

        //将所有节点增加到nodes集合中
        nodes.addAll(authorNodes);
        //将所有关系增加到edges集合中
        edges.addAll(authorEdges);
        //将关系和节点列表添加到结果集中
        results.put("nodes",nodes);
        results.put("edges",edges);

        results.put("authordetail",authordetail);//机构详细信息
        results.put("hotwords",hotworddata);//机构相关热词
        results.put("orgs",orgs);//机构相关专家

        Map<String,Object> articelNum = new HashMap<String,Object>();
        articelNum.put("key","articelNum");
        articelNum.put("num",articleIdParams.size());
        articelNum.put("text","新闻动态");
        Map<String,Object> paperNum = new HashMap<String,Object>();
        paperNum.put("key","paperNum");
        paperNum.put("num",paperIdParams.size());
        paperNum.put("text","论文");
        Map<String,Object> patentNum = new HashMap<String,Object>();
        patentNum.put("key","patentNum");
        patentNum.put("num",patentIdParams.size());
        patentNum.put("text","专利");

        techNums.add(articelNum);
        techNums.add(paperNum);
        techNums.add(patentNum);

        results.put("techNums",techNums);//机构相关技术动态数量
        return results;
    }

    /**
     * 获取某个专家相关新闻动态信息列表
     * @param  authorId 专家ID
     * @return
     */
    public  List<Map<String,Object>>  authorTechDetails(Integer topicId,Integer authorId){
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("authorId",authorId);
        return authorDao.getAuthorTechDetails(params);
    }
    /**
     * 获取某个专家相关论文列表
     * @param  authorId 专家ID
     * @return
     */
    public  List<Map<String,Object>>  authorPaperDetails(Integer topicId,Integer authorId){
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("authorId",authorId);
        return authorDao.getAuthorPaperDetails(params);
    }
    /**
     * 获取某个专家相关专利列表
     * @param  authorId 专家ID
     * @return
     */
    public  List<Map<String,Object>>  authorPatentDetails(Integer topicId,Integer authorId){
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("authorId",authorId);
        return authorDao.getAuthorPatentDetails(params);
    }
    /**
     * 获取地图上某个点相关的专家列表
     * @param  topicId 专家ID
     * @param  coordinate 坐标
     * @return
     */
    public List<Map<String,Object>>  getAuthorDetailForMap(Integer topicId,String coordinate){
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("coordinate",coordinate);
        return authorDao.getAuthorDetailForMap(params);
    }

    public  List<Map<String,Object>>  authorPaperDetails(Map<String,Object> params){
        return authorDao.getAuthorPaperDetails(params);
    }

    public  List<Map<String,Object>>  authorTechDetails(Map<String,Object> params){
        return authorDao.getAuthorTechDetails(params);
    }
    public  List<Map<String,Object>>  authorPatentDetails(Map<String,Object> params){
        return authorDao.getAuthorPatentDetails(params);
    }
}
